/* 
 * File:   Command.h
 * Author: Gab'z
 *
 * Created on 25 mai 2012, 13:50
 */

#ifndef COMMAND_H
#define	COMMAND_H

#include <iostream>
#include <string>
#include <sstream>
#include <typeinfo>
#include "../../exception/CommandException.h"
#include "../../log/LogSystem.h"

namespace calculator {
    class Context;

    /**
     * Classe de base des commandes.
     * Non instanciable.
     * Design Pattern Command.
     */
    class Command {
    public:

        /**
         * Méthode virtuelle pure d'entrée du Design Pattern Command.
         * Utilisation avec le Design Pattern Template Method, la méthode 
         * appelée est précisée par les filles.
         */
        virtual void execute() const throw (CommandException) = 0;

        /**
         * Vérifie si la commande est exécutable.
         * Méthode virtuelle pure appelée avant execute() afin de 
         * vérifier les paramètres et l'état des piles. @see Parameters, StackList, Stack
         * @return une std::string vide si la commande est exécutable,
         * sinon renvoie soit la raison de l'erreur dans la plupart des cas,
         * ou dans le cas d'une Expression renvoie le restant non exécuté de l'expression.
         */
        virtual std::string isExecutable() const = 0;

        /**
         * Clone la commande.
         * On ne peut pas créer de commandes (sauf des constantes) directement,
         * c'est le rôle du CommandManager, on a cependant besoin de les copier
         * pour les sauvegardes et la fonction UNDO/REDO.
         * @return une copie de la commande
         */
        virtual Command* clone() const = 0;
        
        /**
         * Destructeur de Command.
         */
        virtual ~Command();
        
        /**
         * Renvoie la Command sous la forme d'une std::string.
         * D'une manière générale on retourne le nom de la commande,
         * dans le cas des Constant, on retourne la valeur sous la forme.
         * d'une chaîne.
         * @return la Command sous la forme d'une std::string.
         */
        virtual std::string toString() const;
        
    protected:
        
        /**
         * Le nom de la commande
         */
        const std::string _name;

        /**
         * Constructeur de Command.
         * Chaque commande est défini par son nom.
         * @param name le nom de la commande.
         */
        Command(const std::string name);

    private:
        static Logger* log;

    };

}
#endif	/* COMMAND_H */

